﻿using System.Collections.Generic;
using FireStarter.Base.BusinessObjectMerger;
using Habanero.Base;
using Habanero.Testability;
using NUnit.Framework;

namespace Firestarter.Test.Base.BusinessObjectMerger
{
    class TestCompareResults
    {

        [Test]
// ReSharper disable InconsistentNaming
        public void Test_CompareResults_Construct_WithListOfIBOError()
        {
            //---------------Set up test pack-------------------
            var list = new List<IBOError>();
            //---------------Assert Precondition----------------
            Assert.IsInstanceOf<List<IBOError>>(list);
            //---------------Execute Test ----------------------
            var result = new CompareResult(list);

            //---------------Test Result -----------------------
            Assert.IsNotNull(result.CompareFailureList);
            Assert.AreEqual(0, result.CompareFailureList.Count);
            Assert.IsTrue(result.AreEqual);
        }

        [Test]
        public void Test_CompareResults_Construct_WithCompareFailureMessage()
        {
            //---------------Set up test pack-------------------
            var failureMessage = GetRandomString();
            var message = new CompareFailureMessage(failureMessage);

            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            var result = new CompareResult(message);

            //---------------Test Result -----------------------
            Assert.IsNotNull(result.CompareFailureList);
            Assert.AreEqual(1, result.CompareFailureList.Count);
            Assert.AreEqual(failureMessage, result.CompareFailureList[0].Message);
            Assert.IsFalse(result.AreEqual);
        }

        [Test]
        public void Test_CompareResults_ConstructWithStringErrorMessage()
        {
            //---------------Set up test pack-------------------
            var failureMessage = GetRandomString();

            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            var result = new CompareResult(failureMessage);

            //---------------Test Result -----------------------
            Assert.IsNotNull(result.CompareFailureList);
            Assert.AreEqual(1, result.CompareFailureList.Count);
            Assert.AreEqual(failureMessage, result.CompareFailureList[0].Message);
            Assert.IsFalse(result.AreEqual);
        }

        [Test]
        public void Test_AddFailure_WhenCalledOnceWithErrorMessage_ShouldReturnOneCompareFailureAndAreEqual_False()
        {
            //---------------Set up test pack-------------------
            var result = CreateCompareResultWithIBOErrorList();

            var errorMessage = GetRandomString();
            //---------------Assert Precondition---------------- 
            Assert.AreEqual(0, result.CompareFailureList.Count);
            Assert.IsTrue(result.AreEqual);
            //---------------Execute Test ----------------------
            result.AddFailure(errorMessage);
            //---------------Test Result -----------------------
            Assert.AreEqual(1, result.CompareFailureList.Count);
            Assert.IsFalse(result.AreEqual);
        }

        [Test]
        public void Test_AddFailure_WhenCalledTwiceWithErrorMessage_ShouldReturnTwoCompareFailureAndAreEqual_False()
        {
            //---------------Set up test pack-------------------
            var result = CreateCompareResultWithIBOErrorList();
            
            var errorMessage = GetRandomString();
            var errorMessage2 = GetRandomString();
            //---------------Assert Precondition---------------- 
            Assert.AreEqual(0, result.CompareFailureList.Count);
            Assert.IsTrue(result.AreEqual);
            //---------------Execute Test ----------------------
            result.AddFailure(errorMessage);
            result.AddFailure(errorMessage2);
            //---------------Test Result -----------------------
            Assert.AreEqual(2, result.CompareFailureList.Count);
            Assert.IsFalse(result.AreEqual);
        }

        [Test]
        public void Test_AddFailure_WhenCalledManyTimesWithErrorMessage_ShouldReturnManyCompareFailureAndAreEqual_False()
        {
            //---------------Set up test pack-------------------
            var result = CreateCompareResultWithIBOErrorList();

            var errorMessage = GetRandomString();
            var errorMessage2 = GetRandomString();
            var errorMessage3 = GetRandomString();
            //---------------Assert Precondition---------------- 
            Assert.AreEqual(0, result.CompareFailureList.Count);
            Assert.IsTrue(result.AreEqual);
            //---------------Execute Test ----------------------
            result.AddFailure(errorMessage);
            result.AddFailure(errorMessage2);
            result.AddFailure(errorMessage3);
            //---------------Test Result -----------------------
            Assert.AreEqual(3, result.CompareFailureList.Count);
            Assert.IsFalse(result.AreEqual);
        }


        [Test]
        public void Test_AddFailure_WhenCalledWithCompareFailureMessage_ShouldReturnCompareFailureAndAreEqual_False()
        {
            //---------------Set up test pack-------------------
            var result = CreateCompareResultWithIBOErrorList();

            var compareFailureMessage = new CompareFailureMessage(GetRandomString());
            //---------------Assert Precondition---------------- 
            Assert.AreEqual(0, result.CompareFailureList.Count);
            //---------------Execute Test ----------------------
            result.AddFailure(compareFailureMessage);
            //---------------Test Result -----------------------
            Assert.AreEqual(1, result.CompareFailureList.Count);
            Assert.IsFalse(result.AreEqual);
        }

        [Test]
        public void Test_CompareFailures_WhenCalled_ShouldReturnFailureMessageContainingCompareFailureMessages()
        {
            //---------------Set up test pack-------------------
            var errorMessage = GetRandomString();
            var compareResult = new CompareResult(errorMessage);

            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            var message = compareResult.CompareFailures();
            //---------------Test Result -----------------------
            StringAssert.Contains(errorMessage, message); 
           
        }
        // ReSharper restore InconsistentNaming

        private static IList<IBOError> CreateNewFailureList()
        {
            IList<IBOError> failureList = new List<IBOError>();

            return failureList;
        }

        private static string GetRandomString()
        {
            return RandomValueGen.GetRandomString();
        }

// ReSharper disable InconsistentNaming
        private static CompareResult CreateCompareResultWithIBOErrorList()
// ReSharper restore InconsistentNaming
        {
            var list = CreateNewFailureList();
            return new CompareResult(list);
        }
    }
}
